<?php

abstract class RTO {

    private static $rdo = null;
    private $sql_query;
    private $stmt;
    private $limit;
    private $N = 0;

    public abstract function getPrimaryKey();

    public abstract function getName();

    public abstract function getNamespace();

    public function getKeyAI() {
        return null;
    }

    public function save() {
        if (RTO::$rdo != null) {
            return RTO::$rdo->makeConnection()->update($this)?true:false;
        }
        return false;
    }

    public function map() {
        if (RTO::$rdo != null) {
            RTO::$rdo->makeConnection()->map($this);
        }
    }

    public static function connect(&$rdo) {
        RTO::$rdo = $rdo;
    }

    public static function insert(&$rto) {
        if (RTO::$rdo != null) {
            return RTO::$rdo->makeConnection()->insert($rto);
        }
        return false;
    }
    
    public static function isExisted($table,$columns){
        if (RTO::$rdo != null) {
            return RTO::$rdo->makeConnection()->isExisted($table,$columns);
        }
        return false;
    }

    public static function delete(&$rto) {
        if (RTO::$rdo != null) {
            return RTO::$rdo->makeConnection()->delete($rto)?true:false;
            $rto = null;
        }
        return false;
    }

    public static function disconnect() {
        RTO::$rdo = null;
    }

    public function prepareData($sql) {
        $this->sql_query = $sql;
        $this->limit = null; // Reset limit 
    }

    public function getSQLQuery() {
        return $this->sql_query;
    }

    public function exec($input_param = array()) {
        if (RTO::$rdo != null && $this->sql_query != "") {
            $this->N = 0;
            $this->closeFetch();
            $this->stmt = RTO::$rdo->makeConnection()->prepare(
                    $this->sql_query
                    . ($this->limit != null ? " LIMIT " . $this->limit["start"] . "," . $this->limit["end"] : "")
            );
            $this->stmt->execute($input_param);
            return true;
        }
        return false;
    }

    public function fetch() {
        if (RTO::$rdo != null && $this->stmt != null) {
            $result = $this->stmt->fetch(PDO::FETCH_ASSOC);
            if ($result) {
                foreach ($result as $key => $value) {
                    if ($value != null) {
                        $this->$key = $value;
                    }else{
                        $this->$key = null;
                    }
                }
                return true;
            }
        }
        return false;
    }

    public function closeFetch() {
        if ($this->stmt != null) {
            $this->stmt->closeCursor();
            unset($this->stmt);
        }
    }

    public function prepareLimit($start, $end) {
        if($this->limit == null){
            $this->limit = array();
        }
        $this->limit["start"] = $start;
        $this->limit["end"] = $end;
    }

    public function findCount($input_param = array()) {
        if (RTO::$rdo != null && $this->sql_query != "") {
            $conn = RTO::$rdo->makeConnection();
            $sql = $conn->convertToCountStatement($this->sql_query);
            $stmt = $conn->prepare($sql);
            $stmt->execute($input_param);
            $n = $stmt->fetchFirst();
            $stmt->closeCursor();
            $this->N = intval($n);
            return $this->N;
        }
        return 0;
    }

    public function getCount() {
        return $this->N;
    }

}
